package com.ss.plugins.ws.collect.model;


import com.ss.plugins.ws.collect.annotation.OnlyAttribute;
import lombok.extern.slf4j.Slf4j;

import javax.websocket.Session;
import java.lang.reflect.Field;


/**
 *
 *  * 单页面不可重复的超k类
 *  * 子类必须实现Equals和hashCode方法
 *
 * @author xia17
 * @description: TODO
 * @date 2019/5/11 15:22
 *
 */
@Slf4j
public class SessionBean {

    private Session session;

    public final void setSession(Session session){
        this.session = session;
    }

    public final Session getSession(){
        return this.session;
    }

    /**
     * 反射判断唯一注解属性。
     * @param sessionBean 对比的对象
     * @return 是否相等
     */
    public final boolean myEquals(SessionBean sessionBean) {
        //获取对象的所有属性
        if (sessionBean.getClass()!=this.getClass()){
            throw new ClassCastException("对比的对象不是相同的对象");
        }
         Field[] fields = sessionBean.getClass().getDeclaredFields();
         boolean z = true;
         for (Field field : fields) {
             field.setAccessible(true);
             //获取有注解标识的字段
             if (field.isAnnotationPresent(OnlyAttribute.class)){
                 Object o ;
                 Object o1;
                 //获取字段值
                 try {
                     o = field.get(this);
                     o1 = field.get(sessionBean);
                 }catch (Exception e){
                     e.printStackTrace();
                     throw new RuntimeException("反射发生异常");
                 }
                 //判断是否相等（有一处不同就返回false）
                 if ( o == null && o1 != null){
                     return false;
                 }
                 if ( o != null && o1 == null){
                     return false;
                 }
                 if (o != null ){
                     if (!o.equals(o1)){
                         return false;
                     }
                 }
                 //如果运行到这说明有注解
                 if (z){
                     z = false;
                 }
             }
         }
         //如果该对象没有该注解则报错
         if (z){
             throw new RuntimeException("使用Xia17SocketBean时请至少添加一个唯一属性（@OnlyAttribute注解）");
         }
        return true;
     }

    /**
     * 复制当前对象的唯一属性(标有@OnlyAttribute 注解的字段)
     * @return  返回一个含有唯一属性字段值的对象 SessionBean
     */
    public final SessionBean copyOnlyAttribute(){
        //获取类对象
        Class<? extends SessionBean> clazz = this.getClass();
        SessionBean copy ;
        try {
            copy = clazz.newInstance();
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                //获取有注解标识的字段
                if (field.isAnnotationPresent(OnlyAttribute.class)) {
                    field.set(copy,field.get(this));
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("copy唯一属性时发生反射异常");
            throw new RuntimeException("copy唯一属性时发生反射异常");
        }
        return copy;
    }

}
